package com.bcx.wind.workflow.db.connection;

import com.bcx.wind.workflow.db.datasource.WindDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;

/**
 * 工作流数据库链接
 *
 * @author zhanglei
 */
public class WindConnection implements InvocationHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(WindConnection.class);

    private static final String CLOSE = "close";

    /**
     * 真实的数据库链接
     */
    private Connection connection;

    /**
     * 代理连接
     */
    private Connection proxyConnection;

    /**
     * 自定义数据源
     */
    private WindDataSource dataSource;

    /**
     * 开始使用连接时间
     */
    private long startUseTime;


    public WindConnection(Connection connection,WindDataSource dataSource){
        this.connection = connection;
        this.dataSource = dataSource;
        this.proxyConnection = (Connection) Proxy.newProxyInstance(Connection.class.getClassLoader(),new Class[]{Connection.class},this);
    }

    public Connection getConnection() {
        return connection;
    }

    public WindDataSource getDataSource() {
        return dataSource;
    }

    public long getStartUseTime() {
        return startUseTime;
    }

    public void setStartUseTime(long startUseTime) {
        this.startUseTime = startUseTime;
    }

    public Connection getProxyConnection() {
        return proxyConnection;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if(CLOSE.hashCode()==method.getName().hashCode() && CLOSE.equals(method.getName())){
            if(LOGGER.isDebugEnabled()){
                LOGGER.debug("connection "+this+" back to connectionPool!");
            }
            this.dataSource.pushConnection(this);
            return null;
        }
        return method.invoke(connection,args);
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if(obj instanceof WindConnection){
            return this.connection.hashCode() == ((WindConnection) obj).connection.hashCode();
        }else if(obj instanceof Connection){
            return this.connection.hashCode() == obj.hashCode();
        }
        return false;
    }
}
